package cn.itcast.service.impl;

import cn.hutool.json.JSONUtil;
import cn.itcast.dao.SetmealDao;
import cn.itcast.entity.PageResult;
import cn.itcast.pojo.Address;
import cn.itcast.pojo.CheckGroup;
import cn.itcast.pojo.CheckItem;
import cn.itcast.pojo.Setmeal;
import cn.itcast.service.SetmealService;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealDao setmealDao;

    private FileWriter writer;

    @Transactional
    @Override
    public void add(Setmeal setmeal, Integer[] checkgroupIds) {
        //保存体检套餐基础数据
        setmealDao.add(setmeal);
        //保存体检套餐关联体检组数据
        if (checkgroupIds != null) {
            setCheckGroupAssociation(setmeal.getId(), checkgroupIds);
        }
    }

    @Override
    public PageResult pageQuery(Integer currentPage, Integer pageSize, String queryString) {
        PageHelper.startPage(currentPage, pageSize);
        Page<Setmeal> page = setmealDao.findByCondition(queryString);
        return new PageResult(page.getTotal(), page.getResult());
    }

    @Override
    public Integer[] selectedCheckGroupIds(Integer setMealId) {
        return setmealDao.findCheckGroupAssociationIds(setMealId);
    }

    @Override
    public Setmeal findById(Integer id) {
        return setmealDao.findById(id);
    }

    @Transactional
    @Override
    public void update(Setmeal setmeal, Integer[] checkgroupIds) {
        //更新体检套餐基础信息
        setmealDao.update(setmeal);
        //删除之前体检套餐与体检组的关联信息
        setmealDao.deleteCheckGroupAssociation(setmeal.getId());
        //保存新的体检套餐与体检组的关联信息
        if (checkgroupIds != null) {
            setCheckGroupAssociation(setmeal.getId(), checkgroupIds);
        }
    }

    @Transactional
    @Override
    public void deleteById(Integer id) {
        //删除体检套餐与体检组的关联数据
        setmealDao.deleteCheckGroupAssociation(id);
        //删除体检套餐数据
        setmealDao.deleteById(id);
    }

    @Override
    public List<Setmeal> findAll() {
        return setmealDao.findAll();
    }

    @Override
    public Setmeal findSetmealDetail(Integer id) {
        return setmealDao.findDetailsById(id);
    }

    @Override
    public List<Map<String, Object>> findSetmealOrderedCount() {
        return setmealDao.findSetmealOrderedCount();
    }

    /**
     * 根据套餐ID查询所有检查组
     *
     * @param id
     * @return
     */
    @Override
    public List<CheckGroup> findCheckgroupById(Integer id) {
        return setmealDao.findCheckgroupById(id);
    }

    /**
     * 根据检查组id查询所有检查项
     *
     * @param id
     * @return
     */
    @Override
    public List<CheckItem> findCheckitem(Integer id) {

        return setmealDao.findCheckItemByid(id);
    }

    /**
     * 根据分院id查询分院详情
     *
     * @param addressId
     * @return
     */
    @Override
    public Address findByAddressId(Integer addressId) {
        return setmealDao.findByAddressId(addressId);
    }

    /**
     * 根据id生成对应检查组的静态页面文件
     *
     * @param id
     * @throws IOException
     */
    @Override
    public void createStaticHtml(Integer id) {
        try {
            Setmeal setmeal = findById(id);
            // 根据id查询出所有检查组
            List<CheckGroup> groupList = findCheckgroupById(id);
            // 根据检查组id查询出所有检查项
            for (CheckGroup checkGroup : groupList) {
                List<CheckItem> checkItemList = findCheckitem(checkGroup.getId());
                //把所有检查项集合设置为checkGroup属性
                checkGroup.setCheckItems(checkItemList);
            }
            // 把检查组检查项设置为Setmeal属性 封装返回
            setmeal.setCheckGroups(groupList);

            // 创建配置类
            Configuration configuration = new Configuration(Configuration.getVersion());
            // 设置模板的上下文，以及加载模板的路径 （模板存放路径）
            String classpath = this.getClass().getResource("/").getPath();
            configuration.setDirectoryForTemplateLoading(new File(classpath + "/template"));
            // 设置模板的编码格式
            configuration.setDefaultEncoding("UTF-8");
            // 加载模板文件,获取模板对象
            Template template = configuration.getTemplate("setmeal_detail.ftl");
            // 获取项目的根目录
            // String basePath = req.getServletContext().getRealPath("/");
            File htmlFile = new File(classpath + "/html");
            System.out.println(htmlFile.getAbsolutePath());
            // 判断文件目录是否存在
            if (!htmlFile.exists()) {
                // 如果文件不存在
                htmlFile.mkdir();
            }
            // 得到生成的文件名 （根据id生成套餐详情的html的文件名）
            // String fileName = bsahPath + id + ".html";//这里先写死后续优化
            String fileName = "E:\\chaunzhi-v1\\chaunzhi-health\\itcast-health-parent\\itcast-health-mobile-html\\pages\\" + "setmeal_detail" + id + ".html";
            System.out.println(fileName);
            // 创建html文件
            File file = new File(fileName);
            // 如果文件存在就先删除再生成
            if (file.exists()) {
                file.delete();
            }
            // 获取文件输出流
            writer = new FileWriter(file);

            // 生成html(将数据模型填充到模板中)
            Map<String, Object> map = new HashMap<>();

            map.put("setmeal", JSONUtil.toJsonStr(setmeal));
            map.put("imgUrl", setmeal.getImg());

            template.process(map, writer);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (writer != null) {
                try {
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 初始化生成所有静态页面
     */
    public void init() {
        List<Setmeal> list = findAll();
        list.stream().forEach(setmeal -> createStaticHtml(setmeal.getId()));
    }


    /**
     * 保存检查组和检查项关联信息
     *
     * @param setmealId
     * @param checkGroupIds
     */
    private void setCheckGroupAssociation(Integer setmealId, Integer[] checkGroupIds) {
        Stream.of(checkGroupIds).forEach(checkGroupId -> setmealDao.setCheckGroupAssociation(setmealId, checkGroupId));
    }

}
